// Copyright (C) Microsoft Corporation. All rights reserved.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Xml;

namespace Microsoft.DDSolutions.TfsAdmin
{
    public class RoleConfig
    {
        private Hashtable roleMappings = new Hashtable();
        private XmlDocument xDoc = new XmlDocument();
        
        /// <summary>
        /// RoleConfig parses out the RoleConfig.xml file.
        /// Support for WSS 3.0 was added by changing the signature of ctor of this class
        /// to expect a bool inidicating whether the team site being connected to is a 
        /// WSS 3.0 site
        /// </summary>
        /// <param name="isWSS3">Indicates if the team project site being connected to is a WSS 3.0 site</param>
        public RoleConfig(bool isWSS3)
        {
            
            string filename = "RoleConfig.xml";
            xDoc.Load(filename);
                        
            XmlNodeList mappings = xDoc.GetElementsByTagName("TFSRole");

            foreach (XmlNode map in mappings)
            {
                XmlAttributeCollection attribs = map.Attributes;
                XmlNode n = attribs.GetNamedItem("name");
                string TFSRole = n.InnerText;

                RoleMappings TfsRoleMap = new RoleMappings();
                TfsRoleMap.TfsRole = TFSRole;


                XmlDocument xDocMappingRoles = new XmlDocument();
                xDocMappingRoles.LoadXml(map.InnerXml);

                XmlNodeList SystemRoles = xDocMappingRoles.GetElementsByTagName("System");
                foreach (XmlNode SystemRole in SystemRoles)
                {
                    XmlAttributeCollection mapattribs = SystemRole.Attributes;

                    XmlNode SystemNameAttrib = mapattribs.GetNamedItem("name");
                    string System = SystemNameAttrib.InnerText;

                    // Changed the assignment of the XmlNode roleAttrib to be determined by if this is a WSS 3.0 
                    // team project site.
                    XmlNode roleAttrib;
                    if ((System == "SharePoint") && isWSS3)
                    {
                        // If this is a WSS 3.0 site and there is no wss3role attribute assigned it will
                        // revert to using the role atribute in the same manner as the previous release
                        // by way of the catch. Is this best form?? Couldn't readily think of a way to
                        // determine if the attribute existed without enumerating across the attributes 
                        // thus opted to perform the catch as the enumeration across the attributes seems 
                        // to provide little added value in form and none in function.
                        try
                        {
                            roleAttrib = mapattribs.GetNamedItem("wss3role");
                        }
                        catch
                        {                            
                            roleAttrib = mapattribs.GetNamedItem("role");

                        }
                    }
                    else
                    {
                        roleAttrib = mapattribs.GetNamedItem("role");
                    }

                    string Role = roleAttrib.InnerText;

                    if(System == "SharePoint")
                    {
                        
                        TfsRoleMap.SharePointRoles.Add(Role);
                    }
                    else if(System == "ReportServer")
                        TfsRoleMap.ReportServerRoles.Add(Role);
                }

                roleMappings.Add(TFSRole, TfsRoleMap);
            }

        }

        public ReadOnlyCollection<string> GetRolesBySystem(string key, string subsystem)
        {
            RoleMappings Roles = (RoleMappings)roleMappings[key]; // the key here is a TFS Role.

            if (Roles == null)
                return null;

            if (subsystem == "SharePoint")
            {
                return new ReadOnlyCollection<string>(Roles.SharePointRoles);
            }
            else if (subsystem == "ReportServer")
            {
                return new ReadOnlyCollection<string>(Roles.ReportServerRoles);
            }
            else
                return null;
        }

        public void RemoveRoleFromMappings(string roleName, string system)
        {

            RoleMappings Roles = (RoleMappings)roleMappings[roleName]; // the key here is a TFS Role.

            if (system == "SharePoint")
            {
                Roles.SharePointRoles.Remove(roleName);
            }
            else if (system == "ReportServer")
            {
                Roles.ReportServerRoles.Remove(roleName);
            }
        }

        public void AddRoleToMappings(string roleName, string system)
        {

            RoleMappings Roles = (RoleMappings)roleMappings[roleName]; // the key here is a TFS Role.

            if (system == "SharePoint")
            {
                Roles.SharePointRoles.Add(roleName);
            }
            else if (system == "ReportServer")
            {
                Roles.ReportServerRoles.Add(roleName);
            }
        }

    }

}
